/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yoga.algo.coding.floating;

import java.util.Collections;
import yoga.probability.Probablistics;

/**
 *
 * @author Yogev Montekyo
 */
public class FloatDataArray
{
    private double[] m_data;

    public FloatDataArray(int size)
    {
        m_data = new double[size];
        reset();

    }

    public int size()
    {
        return m_data.length;
    }

    public void reset()
    {
        for (int i = 0; i < m_data.length; i++)
        {
            m_data[i] = 0;
        }
    }

    public void setFloat(int index, double value)
    {
        if ((index < 0) || (index >= m_data.length))
        {
            throw new ArrayIndexOutOfBoundsException("Index " + index + " is out of " + m_data.length + " array size");
        }

        m_data[index] = value;
    }

    public double getFloat(int index)
    {
        if ((index < 0) || (index >= m_data.length))
        {
            throw new ArrayIndexOutOfBoundsException("Index " + index + " is out of " + m_data.length + " array size");
        }
        return m_data[index];
    }

    public double[] getFloatDataArray()
    {
        return m_data.clone();
    }

    public void setFloatDataRange(double[] floatDataArray, int startIndex, int endIndex)
    {

        if ((startIndex < 0) || (startIndex >= m_data.length))
        {
            throw new ArrayIndexOutOfBoundsException("StartIndex " + startIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex >= m_data.length)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex < startIndex)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is smaller than start index " + startIndex);
        }

        for (int i = startIndex; i <= endIndex; i++)
        {
            m_data[i] = floatDataArray[i];
        }
    }

    public double[] getFloatDataRange(int startIndex, int endIndex)
    {
        int size = endIndex - startIndex + 1;
        if ((startIndex < 0) || (startIndex >= m_data.length))
        {
            throw new ArrayIndexOutOfBoundsException("StartIndex " + startIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex >= m_data.length)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex < startIndex)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is smaller than start index " + startIndex);
        }

        double[] dataRange = new double[size];
        int indexTarget = 0;
        for (int indexSource = startIndex; indexSource < endIndex; indexSource++)
        {
            dataRange[indexTarget++] = m_data[indexSource];
        }
        return dataRange;
    }

    public void contaminatedRandomFloatNumber(double range)
    {
        int index = Probablistics.getRandomInt(m_data.length);
        double mutationRange = Probablistics.getRandomFloatWithinRange(0, range);
        if (Probablistics.randomBoolean(0.5))
        {
            mutationRange = (-mutationRange);
        }
        m_data[index] += mutationRange;
    }

    
    public void contaminatedRandomFloatNumber(double lowerBoundary, double upperBoundary)
    {
        int index = Probablistics.getRandomInt(m_data.length);
        m_data[index] = Probablistics.getRandomFloatWithinRange(lowerBoundary, upperBoundary);
    }

    public void swapFloatRangeWith(FloatDataArray floatDataArray, int startIndex, int endIndex)
    {
        if ((startIndex < 0) || (startIndex >= m_data.length))
        {
            throw new ArrayIndexOutOfBoundsException("StartIndex " + startIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex >= m_data.length)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is out of " + m_data.length + " array size");
        }
        if (endIndex < startIndex)
        {
            throw new ArrayIndexOutOfBoundsException("EndIndex " + endIndex + " is smaller than start index " + startIndex);
        }

        for (int index = startIndex; index < endIndex; index++)
        {
            double temp = m_data[index];
            m_data[index] = floatDataArray.m_data[index];
            floatDataArray.m_data[index] = temp;
        }
    }

    public FloatDataArray getCopy()
    {
        FloatDataArray floatDataArrayCopy = new FloatDataArray(m_data.length);
        floatDataArrayCopy.m_data = this.m_data.clone();
        return floatDataArrayCopy;
    }
//    public void crossWithAnother(FloatDataArray floatDataArray, int index)
//    {
//        if (m_data.length != floatDataArray.m_data.length)
//        {
//            throw new IllegalArgumentException("FloatDataArrays cannot be of different size");
//        }
//        
//        double[] leftAfterIndex = floatDataArray.getFloatDataRange(index, m_data.length-1);
//        double[] rightAfterIndex = this.getFloatDataRange(index,  m_data.length-1);
//        this.setFloatDataRange(leftAfterIndex, index, m_data.length-1);         
//        floatDataArray.setFloatDataRange(rightAfterIndex, index, m_data.length-1);
//        
//    }
}
